/*
 * Metadata.java
 *
 *  created: 20.8.2011
 *  charset: UTF-8
 *  license: MIT (X11) (See LICENSE file for full license)
 */
package cz.mp.k3bg.core;

import cz.mp.k3bg.log.LoggerManager;
import cz.mp.k3bg.util.TagUtils;
import cz.mp.util.DateUtils;
import cz.mp.util.FileUtils;
import cz.mp.util.StringUtils;
import java.util.logging.Logger;


/**
 * Třída {@code Metadata} obsahuje základní informace o knize: 
 * název, jméno autora, jazyk, identifikační číslo, a další.
 * Název, jméno autora, jazyk, identifikační číslo jsou povinné položky.
 * 
 * @author Martin Pokorný
 * @version 0.1
 */
public class Metadata {

    private static final boolean DEBUG = false;
    private static final Logger logger =
            LoggerManager.getLogger(Metadata.class, DEBUG);
    
    /** Název díla. 
     * Povinná položka. */
    private String title = "";
    
    /** Autor díla. 
     * Povinná položka. */
    private String author = "";
    
    /** Jazyk díla. 
     * Povinná položka. */      
    // viz http://www.i18nguy.com/unicode/language-identifiers.html    
    private String lang = "";
    
    /** Identifikace díla, nejspíš ISBN. 
     * Povinná položka. */    
    private String id = "";
    
    /** Příznak, zda identifikace díla je ISBN. */
    private boolean idIsIsbn = true;

    private String genre = "";    
    private String description = "";
    private String publisher = "";
    /** YYYY-MM-DD */
    private String publishDate = "";    
    
    /** Název díla v originále. 
     * Není součástí {@code opf} souboru. */
    private String titleOriginal = "";
    
    // (todo)  rights, source, type, contributor; subject BASICCode
    // v této verzi nepodporováno; zatím nepodstatné :
    
//    /** {@literal <dc:Rights>} */
//    private String rights = "";
//    /** {@literal <dc:Source>} */
//    private String source = "";
//    /** {@literal <dc:Type>} */
//    private String type = "";
//    /** {@literal <dc:Contributor>} */
//    private String contributor = "";
    
//    <dc:Subject BASICCode="subjectcode">
    
    // -----

    /**
     * 
     */
    public Metadata() {
        logger.fine("");
    }
    
    /**
     * 
     * @param title
     * @param author
     * @param lang  např <tt>cs</tt> (ne <tt>cs-CZ</tt>), <tt>en-US</tt>
     * @param isbn 
     */
    Metadata(String title, String author, String lang, String isbn) {
        this(title, author, lang, isbn, true);
    }

    /**
     * 
     * @param title
     * @param author
     * @param lang  např <tt>cs</tt> (ne <tt>cs-CZ</tt>), <tt>en-US</tt>
     * @param id
     * @param isbn 
     */
    Metadata(String title, String author, String lang, String id, 
            boolean isbn) {
        logger.fine("");
        setTitleImpl(title);
        setAuthorImpl(author);
        setLangImpl(lang);
        setIdImpl(id);
        setIdIsIsbnImpl(isbn);
    }
    
    // ----
    
    /**
     * 
     * @param title 
     */
    public void setTitle(String title) {
        setTitleImpl(title);        
    }

    /**
     * 
     * @param title 
     */
    private void setTitleImpl(String title) {
        if (StringUtils.isEmpty(title)) {
            throw new IllegalArgumentException("empty title");
        }
        this.title = TagUtils.escapeXmlInSimpleWay(title.trim());
        logger.info("title = " + this.title);
    }
    
    /**
     * 
     * @return 
     */
    public String getTitle() {
        return TagUtils.unescapeXmlInSimpleWay(title);
    }
    


    /**
     * 
     * @param author 
     */
    public void setAuthor(String author) {
        setAuthorImpl(author);
    }
    
    /**
     * 
     * @param author 
     */
    private void setAuthorImpl(String author) {
        if (StringUtils.isEmpty(author)) {
            throw new IllegalArgumentException("empty author");
        }        
        this.author = TagUtils.escapeXmlInSimpleWay(author);
        logger.info("author = " + this.author);
    }

    /**
     * 
     * @return 
     */
    public String getAuthor() {
        return TagUtils.unescapeXmlInSimpleWay(author);
    }
    
    
    /**
     * 
     * @param lang 
     */
    public void setLang(String lang) {
        setLangImpl(lang);
    }
        
    /**
     * 
     * @param lang  např <tt>cs</tt> (ne <tt>cs-CZ</tt>), <tt>en-US</tt>
     */
    private void setLangImpl(String lang) {
        if (StringUtils.isEmpty(lang)) {
            throw new IllegalArgumentException("empty lang");
        }          
        this.lang = TagUtils.escapeXmlInSimpleWay(lang);
        logger.info("language = " + this.lang);
    }
      
    /**
     * 
     * @return 
     */
    public String getLang() {
        return TagUtils.unescapeXmlInSimpleWay(lang);
    }
    
    
    /**
     * 
     * @param id 
     */
    public void setId(String id) {
        setIdImpl(id);
    }
    
    /**
     * 
     * @param id 
     */
    private void setIdImpl(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new IllegalArgumentException("empty id");
        }
        this.id = TagUtils.escapeXmlInSimpleWay(id);
        logger.info("id = " + this.id);
    }

    
    /**
     * 
     * @return 
     */
    public String getId() {
        return TagUtils.unescapeXmlInSimpleWay(id);
    }
    
    
    /**
     * 
     * @return 
     */
    public String getDescription() {
        return TagUtils.unescapeXmlInSimpleWay(description);
    }

    /**
     * 
     * @param description 
     */
    public void setDescription(String description) {        
        this.description = TagUtils.escapeXmlInSimpleWay(description);
        logger.info("description = " + this.description);
    }

    
    /**
     * 
     * @return 
     */
    public String getGenre() {
        return TagUtils.unescapeXmlInSimpleWay(genre);
    }

    /**
     * 
     * @param genre 
     */
    public void setGenre(String genre) {        
        this.genre = TagUtils.escapeXmlInSimpleWay(genre);
        logger.info("genre = " + this.genre);
    }

    /**
     * 
     * @return 
     */
    public boolean isIdIsIsbn() {
        return idIsIsbn;
    }

    /**
     * 
     * @param idIsbn 
     */
    public void setIdIsIsbn(boolean idIsbn) {
        setIdIsIsbnImpl(idIsbn);
    }

    /**
     * 
     * @param idIsbn 
     */
    private void setIdIsIsbnImpl(boolean idIsbn) {
        logger.info("ISBN ? " + idIsbn);
        this.idIsIsbn = idIsbn;
    }

    
    /**
     * 
     * @return 
     */
    public String getPublishDate() {
        return TagUtils.unescapeXmlInSimpleWay(publishDate);
    }

    /**
     * 
     * @param publishDate 
     */
    public void setPublishDate(String publishDate) {
        this.publishDate = TagUtils.escapeXmlInSimpleWay(publishDate);
        logger.info("publish date = " + this.publishDate);
    }

    /**
     * 
     * @param publishDate 
     */
    public void setPublishDate(java.util.Date publishDate) {
        this.publishDate = DateUtils.formatToYyyyMmDd(publishDate);
        logger.info("publish date = " + publishDate);
    }

    
    /**
     * 
     * @return 
     */
    public String getPublisher() {
        return TagUtils.unescapeXmlInSimpleWay(publisher);
    }

    /**
     * 
     * @param publisher 
     */
    public void setPublisher(String publisher) {
        this.publisher = TagUtils.escapeXmlInSimpleWay(publisher);
        logger.info("publisher = " + this.publisher);
    }

    
    /**
     * 
     * @return 
     */
    public String getTitleOriginal() {
        return TagUtils.unescapeXmlInSimpleWay(titleOriginal);
    }
    
    /**
     * 
     * @param titleOriginal 
     */
    public void setTitleOriginal(String titleOriginal) {
        this.titleOriginal = TagUtils.escapeXmlInSimpleWay(titleOriginal);
        logger.info("original title = " + this.titleOriginal);
    }
    
    
    /**
     * Vytvoří řetězec, který může být použit jako základní jméno (bez přípony)
     * pro výstupní soubory. 
     * <p>
     * Formát:
     * {@literal <author_bez_diakritiky_mezer_>--<title_bez_diakritiky_mezer_>}
     * Maximální délka je {@value FileUtils#MAX_FILENAME_LENGTH}. Pokud je 
     * délka překročena, provede se ořez -- nejprve se ořeže autor, potom
     * je oříznuto na max. délku.
     * 
     * 
     * @return 
     */
    public String createStdBaseFileName() {
        String baseFileName = author + "--" + title + "";
        baseFileName = TagUtils.unescapeXmlInSimpleWay(baseFileName);
        baseFileName = FileUtils.convertToGoodFileName(baseFileName);
        if (baseFileName.length() > FileUtils.MAX_FILENAME_LENGTH) {
            baseFileName = 
                    FileUtils.convertToGoodFileName(title);
        }
        if (baseFileName.length() > FileUtils.MAX_FILENAME_LENGTH) {
            baseFileName = 
                    baseFileName.substring(0, FileUtils.MAX_FILENAME_LENGTH);
        }        
        logger.config(" --> " + baseFileName);
        return baseFileName;
    }
    
    @Override
    public String toString() {
        return super.toString();
    }
    
}   // Metadata
